<template>
    <div class="media-manager-container">
        <div class="row">
            <!-- /.col -->
            <div class="col-md-12">
                <div class="box box-primary" v-loading="boxLoading">
                    <NavBar :list="list"
                            :permissions="permissions"
                            :path="path"
                            :view="view"
                            :canDelete="canDelete"
                            :canUpload="canUpload"
                            :canEdit="canEdit"
                            @changeView="setView"
                            @deleteFile="handleDelete"
                            @mapLoadList="mapLoadList"/>
                    <!-- /.box-body -->
                    <div class="box-footer">
                        <Breadcrumb :nav="nav" @mapLoadList="mapLoadList"/>
                        <GridList v-if="view === 'list'"
                                  :list="list"
                                  :canDelete="canDelete"
                                  :canUpload="canUpload"
                                  :canEdit="canEdit"
                                  @deleteFile="handleDelete"
                                  @listClick="mapToListClick"
                                  @renameOrMove="mapRenameOrMove"
                                  @mapLoadList="mapLoadList"/>
                        <GridTable v-else-if="view === 'table'"
                                   :list="list"
                                   :canDelete="canDelete"
                                   :canUpload="canUpload"
                                   :canEdit="canEdit"
                                   @deleteFile="handleDelete"
                                   @listClick="mapToListClick"
                                   @renameOrMove="mapRenameOrMove"
                                   @mapLoadList="mapLoadList"/>
                    </div>
                    <!-- /.box-footer -->
                    <!-- /.box-footer -->
                </div>
                <!-- /. box -->
            </div>
            <!-- /.col -->
        </div>

        <el-dialog
                :title="previewItem ? previewItem.basename : ''"
                :visible.sync="dialogVisible"
                :before-close="handleClose"
                custom-class="test">
            <div v-if="previewItem" class="preview-container">
                <div v-if="previewItem.fileType === 'video'" class="video-preview">
                    <video controls="controls" preload='none'
                           :src="previewItem['url']"></video>
                </div>
                <div v-else-if="previewItem.fileType === 'image'"
                     class="image-preview">
                    <el-image :src="previewItem.url + '?size=medium'" fit="cover">
                        <div slot="placeholder" class="image-slot">
                            加载中<span class="dot">...</span>
                        </div>
                    </el-image>
                </div>
                <div v-else class="cannot-preview">
                    <div v-html="previewItem['preview']"></div>
                    <div class="cannot-text">暂不支持该类型文件的预览.</div>
                </div>


            </div>
            <div slot="footer" class="dialog-footer" v-if="previewItem">
                <el-link target="_blank"
                         style="margin-right:20px;"
                         :href="`/api/media/download?file=${previewItem['name']}`"
                >
                    下载
                </el-link>
                <el-button type="primary" @click="dialogVisible = false">关闭</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
    import axios      from 'axios';
    import NavBar     from './nav-bar';
    import Breadcrumb from './breadcrumb';
    import GridList   from './grid-list';
    import GridTable  from './grid-table';

    import { basename, getFileExtension, previewType, trim } from "../../utils/parse";

    export default {
        name      : "media-page",
        components: {
            NavBar,
            Breadcrumb,
            GridList,
            GridTable
        },
        props     : {
            propList   : Array,
            propNav    : Array,
            propUrl    : Object,
            permissions: Object,
            csrf       : String,
        },
        data() {
            return {
                list         : [],
                nav          : [],
                url          : {},
                path         : '',
                view         : 'list',
                searchInput  : '',
                boxLoading   : false,
                dialogVisible: false,
                previewItem  : null,
                uploading    : false,
            };
        },
        computed  : {
            canDelete() {
                return this.permissions && !!this.permissions.delete;
            },
            canUpload() {
                return this.permissions && !!this.permissions.upload;
            },
            canEdit() {
                return this.permissions && !!this.permissions.edit;
            },
        },
        created() {
            try {
                this.view = localStorage.getItem('view') || 'list';
            } catch (e) {
                this.view = 'list';
            }

            if (this.propUrl) {
                let path         = this.propUrl[ 'path' ];
                this.searchInput = '/' + trim(path, '/');
            }
        },
        mounted() {
            if (this.propList && this.propNav && this.propUrl) {
                this.fillOtherData(this.propList, this.propNav, this.propUrl);
            } else {
                this.mapLoadList();
            }
        },
        methods   : {
            setView(val) {
                if ([ 'list', 'table' ].includes(val)) {
                    this.view = val;
                    localStorage.setItem('view', val);
                }
            },
            mapRenameOrMove(item) {
                let inputValue = '/' + item[ 'name' ];
                this.$prompt('重命名或移动文件', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText : '取消',
                    inputValue       : inputValue,
                    inputPattern     : /(([\\/])[a-zA-Z0-9\u4e00-\u9fa5\s_@\-^!#$%&+={}\[\]()]+).*[^\/]$/,
                    inputErrorMessage: '路径不正确',
                    beforeClose      : async (action, instance, done) => {
                        if (action === 'confirm') {
                            let value = instance.inputValue;
                            if (inputValue === value) {
                                this.$message.info('无变化.');
                            } else {
                                instance.confirmButtonLoading = true;
                                instance.closeOnClickModal    = false;
                                instance.confirmButtonText    = '光速修改中...';

                                let res                       = await axios({
                                    method: 'post',
                                    url   : '/api/media/move',
                                    data  : {
                                        path: item[ 'name' ],
                                        new : value,
                                    }
                                });
                                instance.confirmButtonLoading = false;
                                instance.closeOnClickModal    = true;
                                console.log('res :', res);
                                if (res.status === 204) {
                                    this.$message.success('创建文件夹成功.');
                                    this.mapLoadList(this.path);

                                } else {
                                    this.$message.warning('创建失败,请联系管理员.');
                                }
                            }
                        }
                        console.log('action :', action);
                        console.log('instance :', instance);
                        done();

                    }
                });

            },
            parseListFile(list) {
                if (typeof list === 'object' && list !== null) {
                    list = Object.values(list);
                }
                return list.map((item) => {
                    item.ext      = getFileExtension(item.name);
                    item.basename = basename(item.name);

                    return item;
                })
            },
            fillOtherData(list, nav, url) {
                this.list = this.parseListFile(list);
                this.nav  = nav;
                this.url  = url;
                this.path = url[ 'path' ];
                this.$nextTick(() => {
                    $('.file-select>input').iCheck({ checkboxClass: 'icheckbox_minimal-blue' });
                })
            },
            handleDelete(files) {
                if (!this.canDelete) {
                    this.$notify({
                        title  : '警告',
                        message: '你没有删除权限,请不要乱操作',
                        type   : 'warning'
                    });
                    return;
                }

                this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText : '取消',
                    type             : 'warning',
                    beforeClose      : async (action, instance, done) => {
                        if (action === 'confirm') {
                            instance.confirmButtonLoading = true;
                            instance.closeOnClickModal    = false;
                            instance.confirmButtonText    = '光速删除中...';

                            let res                       = await this.mapToDelete(files);
                            instance.confirmButtonLoading = false;
                            instance.closeOnClickModal    = true;
                            console.log('res :', res);

                            if (res.status === 204) {
                                this.$message.success('删除成功.');
                                this.mapLoadList();
                            } else {
                                this.$message.warning('删除失败,请联系管理员.');
                            }
                        }
                        console.log('action :', action);
                        console.log('instance :', instance);
                        done();
                    }
                })
            },
            mapToListClick(item) {
                if (item[ 'isDir' ]) {
                    this.mapClickOfDir(item);
                } else {
                    this.mapClickOfFile(item);
                }
            },
            mapClickOfDir(item) {
                this.mapLoadList(item.name);
            },
            mapClickOfFile(item) {
                this.dialogVisible = true;
                let fileType       = previewType(item.ext);
                this.$set(this, 'previewItem', item);

                this.$set(this.previewItem, 'fileType', fileType);
            },
            handleClose(done) {
                this.previewItem   = null;
                this.dialogVisible = false;
                done();
            },
            async mapToDelete(files) {
                return await axios({
                    url   : '/api/media/delete',
                    method: 'delete',
                    data  : {
                        files,
                    }
                })
            },
            async mapLoadList(path = this.path) {
                if (this.boxLoading) return;
                this.boxLoading = true;

                try {
                    let res                = await axios({
                        method: 'get',
                        url   : '/api/media/list',
                        params: {
                            path,
                        }
                    });
                    this.boxLoading        = false;
                    let { list, nav, url } = res.data;
                    this.fillOtherData(list, nav, url);
                    console.log('res :', res);

                } catch (e) {
                    this.boxLoading = false;
                }


            }
        },
    }
</script>

<style lang="less">

    .test {
        max-width: 900px;
        min-width: 360px;
    }

    .preview-container {
        width: 100%;

        .file-icon img {
            display: inline-block;
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    }
</style>
